package com.xisoft.service;

import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.xisoft.base.BaseModel;
import com.xisoft.common.ProcessorException;
import com.xisoft.config.DBConfig;
import com.xisoft.handle.*;
import com.xisoft.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class SysGeneratorService
{
    @Autowired
    DBConfig dbConfig;

    public SysGeneratorService( )
    {
    }

    public void create(String tables)
    {
        String[] var2 = tables.split(",");
        int var3 = var2.length;

        for (int var4 = 0; var4 < var3; ++var4)
        {
            String tableName = var2[var4];
            BaseModel model = new BaseModel();
            model.dbConfig = this.dbConfig;
            model.base_path = this.dbConfig.BASE_PATH;
            model.tablename = tableName;
            model.basePackageName = this.dbConfig.BASEPACKAGENAME;
            model.author = this.dbConfig.AUTHOR;
            HandlerChain handlerChain = new HandlerChainImp();
            handlerChain.addHandler(new CheckHandler());
            handlerChain.addHandler(new DBHandler());
            handlerChain.addHandler(new TempldateHandler());

            try
            {
                handlerChain.handle(model);
            }
            catch (ProcessorException var9)
            {
                System.out.println("代码生产失败，异常；" + var9.getMessage());
                throw new RuntimeException("代码生产失败，异常；" + var9.getMessage());
            }
        }

    }

    public byte[] generatorCode( ) throws IOException
    {
        BufferedInputStream bis = null;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        List< File > sourceFiles = Fileutil.listFile(this.dbConfig.BASE_PATH + File.separator + "src");
        byte[] buffer = new byte[4096];

        for (int i = 0; i < sourceFiles.size(); ++i)
        {
            String fileName = ((File) sourceFiles.get(i)).getPath()
                                                         .replace(this.dbConfig.BASE_PATH.replace("/", "\\"), "");
            ZipEntry zipEntry = new ZipEntry(fileName);
            zipOutputStream.putNextEntry(zipEntry);
            bis = new BufferedInputStream(new FileInputStream((File) sourceFiles.get(i)), 4096);
            boolean var9 = false;

            int read;
            while ((read = bis.read(buffer)) != -1)
            {
                zipOutputStream.write(buffer, 0, read);
            }
        }

        buffer = outputStream.toByteArray();
        zipOutputStream.flush();
        outputStream.flush();
        zipOutputStream.close();
        outputStream.close();
        return buffer;
    }

    public String queryList(Query query) throws Exception
    {
        int total = 0;
        String group = ((DBConfig) SpringHelper.getBean(DBConfig.class)).group;
        List< Entity > list = new LinkedList();
        if (PubEnvUtil.equals("orcl", group))
        {
            list = this.queryListByOrcl(query, group);
            total = this.queryListContByOrcl(query, group);
        }

        if (PubEnvUtil.equals("mysql", group))
        {
            list = this.queryListByMysql(query, group);
            total = this.queryListContByMysql(query, group);
        }

        PageUtils page = new PageUtils((List) list, total, query.getLimit(), query.getPage());
        ResultEntity rest = ResultEntity.ok().put("page", CollectionUtil.transBean2Map(page));
        return CollectionUtil.map2Josn(rest);
    }

    public Integer queryListContByOrcl(Query query, String group) throws Exception
    {
        LinkedList< Object > pramList = new LinkedList();
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT");
        sql.append(" COUNT(dt.table_name) AS total");
        sql.append(" FROM");
        sql.append(" user_tables dt");
        sql.append(" LEFT JOIN user_tab_comments   dtc ON dtc.table_name = dt.table_name");
        sql.append(" LEFT JOIN user_objects        uo ON uo.object_name = dt.table_name");
        sql.append(" WHERE");
        sql.append(" uo.object_type IN (  'TABLE', 'VIEW' )");
        if (!PubEnvUtil.isEmpty(new String[]{StringUtil.valueOf(query.get("tableName"))}))
        {
            String tableName = query.get("tableName").toString().toUpperCase().trim();
            sql.append(" AND (dt.table_name LIKE concat(concat('%', ?), '%')");
            sql.append(" OR dtc.comments LIKE concat(concat('%', ?), '%') ) ");
            pramList.add(tableName);
            pramList.add(tableName);
        }

        return ((Entity) Db.use(group).query(String.valueOf(sql), pramList.toArray()).get(0)).getInt("total");
    }

    public List< Entity > queryListByOrcl(Query query, String group) throws Exception
    {
        LinkedList< Object > pramList = new LinkedList();
        pramList.add(1);
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT");
        sql.append(" *");
        sql.append(" FROM");
        sql.append(" (");
        sql.append(" SELECT");
        sql.append(" dt.table_name  AS engine,");
        sql.append(" dtc.comments   AS tablename,");
        sql.append(" MAX(uo.last_ddl_time) AS createtime,");
        sql.append(" uo.object_type  AS tabletype,");
        sql.append(" ROWNUM   AS rn");
        sql.append(" FROM");
        sql.append(" user_tables dt");
        sql.append(" LEFT JOIN user_tab_comments   dtc ON dtc.table_name = dt.table_name");
        sql.append(" LEFT JOIN user_objects        uo ON uo.object_name = dt.table_name");
        sql.append(" WHERE");
        sql.append(" uo.object_type IN (  'TABLE', 'VIEW' )");
        sql.append(" AND 1 = ?");
        if (!PubEnvUtil.isEmpty(new String[]{StringUtil.valueOf(query.get("tableName"))}))
        {
            String tableName = query.get("tableName").toString().toUpperCase().trim();
            sql.append(" AND ( dt.table_name LIKE concat(concat('%', ?), '%')");
            sql.append("  OR dtc.comments LIKE concat(concat('%', ?), '%') ) ");
            pramList.add(tableName);
            pramList.add(tableName);
        }

        sql.append(" GROUP BY");
        sql.append(" ROWNUM,");
        sql.append(" dt.table_name,");
        sql.append(" dtc.comments,");
        sql.append(" uo.object_type");
        sql.append(" ORDER BY");
        sql.append(" dt.table_name,dtc.comments ");
        sql.append(" )");
        sql.append(" WHERE");
        sql.append(" rn >= ? AND rn <= ?");
        pramList.add(Math.multiplyExact(Integer.valueOf(String.valueOf(query.get("limit"))),
                                        Math.subtractExact(Integer.valueOf(String.valueOf(query.get("page"))), 1)));
        pramList.add(Math.multiplyExact(Integer.valueOf(String.valueOf(query.get("limit"))),
                                        Integer.valueOf(String.valueOf(query.get("page")))));
        return Db.use(group).query(String.valueOf(sql), pramList.toArray());
    }

    public Integer queryListContByMysql(Query query, String group) throws Exception
    {
        LinkedList< Object > pramList = new LinkedList();
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT ");
        sql.append("  COUNT(table_name) AS total");
        sql.append("  FROM information_schema.tables");
        sql.append("  WHERE table_schema='");
        sql.append(((DBConfig) SpringHelper.getBean(DBConfig.class)).USER);
        sql.append("'");
        if (!PubEnvUtil.isEmpty(new String[]{StringUtil.valueOf(query.get("tableName"))}))
        {
            String tableName = query.get("tableName").toString().toUpperCase().trim();
            sql.append(" AND ( table_name LIKE concat(concat('%', ?), '%')");
            sql.append("  OR tableComment LIKE concat(concat('%', ?), '%') ) ");
            pramList.add(tableName);
            pramList.add(tableName);
        }

        return ((Entity) Db.use(group).query(String.valueOf(sql), pramList.toArray()).get(0)).getInt("total");
    }

    public List< Entity > queryListByMysql(Query query, String group) throws Exception
    {
        LinkedList< Object > pramList = new LinkedList();
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT ");
        sql.append("  table_name tableName, engine,");
        sql.append("  table_comment tableComment,");
        sql.append("  create_time createTime ");
        sql.append("  FROM information_schema.tables");
        sql.append("  WHERE table_schema='");
        sql.append(((DBConfig) SpringHelper.getBean(DBConfig.class)).USER);
        sql.append("'");
        if (!PubEnvUtil.isEmpty(new String[]{StringUtil.valueOf(query.get("tableName"))}))
        {
            String tableName = query.get("tableName").toString().toUpperCase().trim();
            sql.append(" AND ( table_name LIKE concat(concat('%', ?), '%')");
            sql.append("  OR tableComment LIKE concat(concat('%', ?), '%') ) ");
            pramList.add(tableName);
            pramList.add(tableName);
        }

        return Db.use(group).query(String.valueOf(sql), pramList.toArray());
    }

    public PageUtils queryListByDic(Query query) throws Exception
    {
        String sql = "SELECT sdt_table_en_name AS tablename,sdt_table_zh_name AS engine,sdt_system_name AS " +
                "tablecomment,sdt_table_type AS tabletype FROM sys_dic_table WHERE 1=?";
        LinkedList< Object > pramList = new LinkedList();
        pramList.add("1");
        if (!ArrayUtil.isEmptyObj(query.get("tableName")))
        {
            sql = sql + " AND sdt_table_en_name =?";
            pramList.add(query.get("tableName").toString().toUpperCase());
        }

        List< Entity > list = Db.use(((DBConfig) SpringHelper.getBean(DBConfig.class)).group)
                                .query(sql, pramList.toArray());
        int total = null == list ? 0 : list.size();
        return new PageUtils(list, total, query.getLimit(), query.getPage());
    }

    public String getColumns(String tableName) throws Exception
    {
        String group = ((DBConfig) SpringHelper.getBean(DBConfig.class)).group;
        List< Entity > list = new LinkedList();
        if (PubEnvUtil.equals("orcl", group))
        {
            list = this.queryColumnByOrcl(tableName, group);
        }

        if (PubEnvUtil.equals("mysql", group))
        {
            list = this.queryColumnByMysql(tableName, group);
        }

        PageUtils page = new PageUtils((List) list, PubEnvUtil.getObjSize(list), 0, 0);
        ResultEntity rest = ResultEntity.ok().put("page", CollectionUtil.transBean2Map(page));
        return CollectionUtil.map2Josn(rest);
    }

    public String dictionary(String tableName) throws Exception
    {
        String group = ((DBConfig) SpringHelper.getBean(DBConfig.class)).group;
        List< Entity > list = new LinkedList();
        if (PubEnvUtil.equals("orcl", group))
        {
            list = this.queryColumnByOrcl(tableName, group);
        }

        if (PubEnvUtil.equals("mysql", group))
        {
            list = this.queryColumnByMysql(tableName, group);
        }

        return CollectionUtil.map2Josn((List) list);
    }

    public List< Entity > queryColumnByOrcl(final String tableName, String group) throws Exception
    {
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT");
        sql.append(" user_tab_columns.table_name       AS table_code,/*表名*/");
        sql.append(" user_tab_comments.comments        AS table_name,/*表备注*/");
        sql.append(" user_tab_columns.column_name      AS col_code,/*列名*/");
        sql.append(" user_col_comments.comments        AS col_name,/*列备注*/");
        sql.append(" user_tab_columns.data_type        AS col_type,/*类型*/");
        sql.append(" decode(user_tab_columns.nullable, 'N', '1', '0') AS nullable,/*是否可空*/");
        sql.append(" user_tab_columns.data_length      AS data_length,/*数据长度*/");
        sql.append(" user_tab_columns.data_precision   AS data_precision,/*数据精度*/");
        sql.append(" decode(pk.column_name, NULL, '0', '1') AS pk/*是否主键*/");
        sql.append(" FROM user_tab_columns    user_tab_columns");
        sql.append(" LEFT JOIN user_tab_comments   user_tab_comments ");
        sql.append(" ON user_tab_columns.table_name = user_tab_comments.table_name");
        sql.append(" JOIN user_col_comments   user_col_comments");
        sql.append(" ON user_col_comments.table_name = user_tab_columns .table_name");
        sql.append(" AND user_col_comments.column_name = user_tab_columns.column_name");
        sql.append(" LEFT JOIN (");
        sql.append(" SELECT");
        sql.append(" user_cons_columns.table_name,");
        sql.append(" user_cons_columns.column_name");
        sql.append(" FROM");
        sql.append(" user_cons_columns user_cons_columns,");
        sql.append(" user_constraints user_constraints");
        sql.append(" WHERE");
        sql.append(" user_cons_columns.constraint_name = user_constraints.constraint_name");
        sql.append(" AND user_constraints.constraint_type = 'P'");
        sql.append(" AND user_constraints.table_name = ?");
        sql.append(") pk ON pk.column_name = user_tab_columns.column_name");
        sql.append(" WHERE");
        sql.append(" user_tab_columns.table_name = ? ");
        sql.append(" ORDER BY user_tab_columns.column_id ASC");
        return Db.use(group).query(String.valueOf(sql), (new LinkedList()
        {
            {
                this.add(tableName);
                this.add(tableName);
            }
        }).toArray());
    }

    public List< Entity > queryColumnByMysql(final String tableName, String group) throws Exception
    {
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT");
        sql.append(" table_name      AS table_code,/*表名*/");
        sql.append(" column_name     AS col_code,/*字段名称*/");
        sql.append(" column_comment  AS col_name,/* 字段说明*/");
        sql.append(" column_type     AS col_type,/*字段类型长度*/");
        sql.append(" is_nullable     AS nullable,/*是否可空*/");
        sql.append(" if(extra = \"auto_increment\", concat(column_key, \"(\", ");
        sql.append(" if(extra = \"auto_increment\", \"自增\", extra), \")\"),");
        sql.append("  column_key)) as pk/*是否主键*/");
        sql.append(" FROM information_schema.columns");
        sql.append(" /*数据库名：jn_power 表名 rpt_cap_hour_ammeter_201810*/");
        sql.append(" WHERE  table_schema = ? AND table_name = ? ;");
        sql.append(" ");
        return Db.use(group).query(String.valueOf(sql), (new LinkedList()
        {
            {
                this.add(((DBConfig) SpringHelper.getBean(DBConfig.class)).table_schema);
                this.add(tableName);
            }
        }).toArray());
    }
}
